package com.luom.springbootinit.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.luom.springbootinit.common.ErrorCode;
import com.luom.springbootinit.constant.CommonConstant;
import com.luom.springbootinit.exception.ThrowUtils;
import com.luom.springbootinit.mapper.BookMapper;
import com.luom.springbootinit.model.dto.book.BookQueryRequest;
import com.luom.springbootinit.model.entity.Book;
import com.luom.springbootinit.model.entity.Category;
import com.luom.springbootinit.model.vo.BookAnalysisVO;
import com.luom.springbootinit.model.vo.BookVO;
import com.luom.springbootinit.model.vo.CountAnalysisVO;
import com.luom.springbootinit.service.BookService;
import com.luom.springbootinit.service.CategoryService;
import com.luom.springbootinit.utils.SqlUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 图书信息服务实现
 */
@Service
@Slf4j
public class BookServiceImpl extends ServiceImpl<BookMapper, Book> implements BookService {

    @Resource
    private CategoryService categoryService;

    @Resource
    private BookMapper bookMapper;

    /**
     * 校验数据
     *
     * @param book
     * @param add  对创建的数据进行校验
     */
    @Override
    public void validBook(Book book, boolean add) {
        ThrowUtils.throwIf(book == null, ErrorCode.PARAMS_ERROR);
        String title = book.getTitle();
        String author = book.getAuthor();
        String publisher = book.getPublisher();
        Date publishDate = book.getPublishDate();
        BigDecimal price = book.getPrice();
        Integer category = book.getCategoryId();
        Integer inventory = book.getInventory();

        // 创建数据时，参数不能为空
        if (add) {
            ThrowUtils.throwIf(StringUtils.isBlank(title), ErrorCode.PARAMS_ERROR);
            ThrowUtils.throwIf(StringUtils.isBlank(author), ErrorCode.PARAMS_ERROR);
            ThrowUtils.throwIf(StringUtils.isBlank(publisher), ErrorCode.PARAMS_ERROR);
            ThrowUtils.throwIf(price == null, ErrorCode.PARAMS_ERROR);
            ThrowUtils.throwIf(category == null, ErrorCode.PARAMS_ERROR);
            ThrowUtils.throwIf(inventory == null, ErrorCode.PARAMS_ERROR);
        }
        // 修改数据时，有参数则校验
        if (StringUtils.isNotBlank(title)) {
            ThrowUtils.throwIf(title.length() > 80, ErrorCode.PARAMS_ERROR, "书名过长");
        }
        if (StringUtils.isNotBlank(author)) {
            ThrowUtils.throwIf(author.length() > 50, ErrorCode.PARAMS_ERROR, "作者过长");
        }
        if (StringUtils.isNotBlank(publisher)) {
            ThrowUtils.throwIf(publisher.length() > 50, ErrorCode.PARAMS_ERROR, "出版社过长");
        }
        if (price != null) {
            ThrowUtils.throwIf(price.compareTo(new BigDecimal("0")) < 0, ErrorCode.PARAMS_ERROR, "价格不能为负数");
        }
        if (category != null) {
            ThrowUtils.throwIf(category < 0, ErrorCode.PARAMS_ERROR, "请确定分类");
        }
        if (inventory != null) {
            ThrowUtils.throwIf(inventory < 0, ErrorCode.PARAMS_ERROR, "库存不能为负数");
        }

    }

    /**
     * 获取查询条件
     *
     * @param bookQueryRequest
     * @return
     */
    @Override
    public QueryWrapper<Book> getQueryWrapper(BookQueryRequest bookQueryRequest) {
        QueryWrapper<Book> queryWrapper = new QueryWrapper<>();
        if (bookQueryRequest == null) {
            return queryWrapper;
        }
        // 从对象中取值
        Integer id = bookQueryRequest.getId();
        String title = bookQueryRequest.getTitle();
        String author = bookQueryRequest.getAuthor();
        String publisher = bookQueryRequest.getPublisher();
        Integer inventory = bookQueryRequest.getInventory();
        Integer categoryId = bookQueryRequest.getCategoryId();
        String sortField = bookQueryRequest.getSortField();
        String sortOrder = bookQueryRequest.getSortOrder();

        // 从多字段中搜索
        /*if (StringUtils.isNotBlank(searchText)) {
            // 需要拼接查询条件
            queryWrapper.and(qw -> qw.like("title", searchText).or().like("content", searchText));
        }*/
        // 模糊查询
        queryWrapper.like(StringUtils.isNotBlank(title), "title", title);
        queryWrapper.like(StringUtils.isNotBlank(author), "author", author);
        queryWrapper.like(StringUtils.isNotBlank(publisher), "publisher", publisher);

        // 精确查询
        queryWrapper.eq(ObjectUtils.isNotEmpty(id), "id", id);
        queryWrapper.eq(ObjectUtils.isNotEmpty(inventory), "inventory", inventory);
        queryWrapper.eq(ObjectUtils.isNotEmpty(categoryId), "categoryId", categoryId);

        // 排序规则
        queryWrapper.orderBy(SqlUtils.validSortField(sortField),
                sortOrder.equals(CommonConstant.SORT_ORDER_ASC),
                sortField);
        return queryWrapper;
    }

    /**
     * 获取图书信息封装
     *
     * @param book
     * @return
     */
    @Override
    public BookVO getBookVO(Book book) {
        if (book == null) {
            return null;
        }
        BookVO bookVO = new BookVO();
        BeanUtils.copyProperties(book, bookVO);
        Integer categoryId = book.getCategoryId();
        Category category = null;
        if (categoryId != null && categoryId > 0) {
            category = categoryService.getById(categoryId);
        }
        if (category != null) {
            bookVO.setCategoryName(category.getName());
        }
        return bookVO;
    }

    /**
     * 分页获取图书信息封装
     *
     * @param bookPage
     * @return
     */
    @Override
    public Page<BookVO> getBookVOPage(Page<Book> bookPage) {
        List<Book> bookList = bookPage.getRecords();
        Page<BookVO> bookVOPage = new Page<>(bookPage.getCurrent(), bookPage.getSize(), bookPage.getTotal());
        if (CollUtil.isEmpty(bookList)) {
            return bookVOPage;
        }
        // 对象列表 => 封装对象列表
        List<BookVO> bookVOList = bookList.stream().map(this::getBookVO).collect(Collectors.toList());

        bookVOPage.setRecords(bookVOList);
        return bookVOPage;
    }

    @Override
    public boolean updateBookInventory(Integer id, boolean isReturned) {
        UpdateWrapper<Book> updateWrapper = new UpdateWrapper<>();
        if (isReturned) {
            updateWrapper.eq("id", id).setSql("inventory = inventory + 1");
        } else {
            updateWrapper.eq("id", id).setSql("inventory = inventory - 1");
        }
        return update(updateWrapper);
    }

    @Override
    public List<BookAnalysisVO> getTop5Book() {
        return bookMapper.getTop5Book();
    }

    @Override
    public CountAnalysisVO getCountAnalysis() {
        return bookMapper.getCountAnalysis();
    }
}
